package com.mhs.sync;

import java.io.IOException;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;

import org.ksoap2.serialization.SoapObject;

import com.mhs.BUS.IRBUS;
import com.mhs.BUS.ThuocBUS;
import com.mhs.DTO.*;
import com.mhs.dataclassification.Entity;
import com.mhs.services.ServiceSync;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.widget.Toast;

public class Sync extends Service {
	private static final String TAG = "ServiceSync";

	public List<HLCDTO> lstExistItems = new ArrayList<HLCDTO>();
	public List<HLCDTO> lstErrorItems = new ArrayList<HLCDTO>();
	
	//Socket m_clientSock;
	@Override
	public IBinder onBind(Intent intent) {
		return null;
	}
	
	@Override
	public void onCreate() {
		Toast.makeText(this, "Service Sync Created", Toast.LENGTH_LONG).show();
		Log.d(TAG, "onCreate");
		try {
			//m_clientSock = new Socket(PublicVariable.getIpserver(), Integer.parseInt(PublicVariable.getPort()));
		} catch (Exception ex) {
			ex.printStackTrace();
			Toast.makeText(this, "Cannot connect to Server! Error:" + ex.getMessage(), Toast.LENGTH_LONG).show();
		}
	}
	
	@Override
	public void onStart(Intent intent, int startid) {
		Toast.makeText(this, "Service Sync Started", Toast.LENGTH_LONG).show();
		Log.d(TAG, "onStart");	
		sync();
	}
	
	@Override
	public void onDestroy() {
		Toast.makeText(this, "Service Sync Stopped", Toast.LENGTH_LONG).show();
		Log.d(TAG, "onDestroy");
//		try {
//			m_clientSock.close();
//		} catch (IOException e) {
//			e.printStackTrace();
//		}
	}
	
	public UserDTO createUserDTO(){
		String IMEI = getIMEI();
		UserDTO user = new UserDTO();
		user.setIMEI(IMEI);
		user.setUserName(IMEI);
		user.setIpClient("");
		user.setPassWord("123456");
		return user;
	}
	
	public String getIMEI(){
		TelephonyManager telephonyManager = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
		String sDeviceID = telephonyManager.getDeviceId();
		return sDeviceID;
	}
	
	private void sync(){
		UserDTO user = createUserDTO();
		if(user != null){
			HLCDTO[] arrIR = sendRequestSync(user);
			if(arrIR != null){
				// khoa nhung record co trong ir
				List<HLCDTO> listIR = findDataUpdateFromIRAndDatabase(arrIR);
				boolean lockRecord = lockRecordHaveIdInIR(arrIR);
				if(lockRecord){
					if(listIR.size() == 0){
						Toast.makeText(this, "Không có dữ liệu nào được đồng bộ!", Toast.LENGTH_LONG).show();
						return;
					}else{
						YeuCauCapNhat yccn = new YeuCauCapNhat();
						Vector<HLCDTO> IR = convertListToVector(listIR);
						yccn.setLstIR(IR);
						// send requestDataFromClient to server
						Data dataReceive = sendRequestDataUpdate(user, IR);
						if(dataReceive == null){
							Toast.makeText(this, "Quá trình nhận dữ liệu xảy ra lỗi!", Toast.LENGTH_LONG).show();
						}else{
							Vector<HLCDTO> vExistItems = convertListToVector(lstExistItems);
							Vector<HLCDTO> vErrorItems = convertListToVector(lstErrorItems);
							boolean checkSend = sendConfirmSyncedData(user, vExistItems, vErrorItems);
							if(checkSend){
								Toast.makeText(this, "Hoàn thành quá trình đồng bộ!", Toast.LENGTH_LONG).show();
							}else{
								Toast.makeText(this, "Quá trình đồng bộ xảy ra lỗi!", Toast.LENGTH_LONG).show();
							}
						}
					}
				}else{
					Toast.makeText(this, "Có lỗi xảy ra khi khóa dữ liệu!", Toast.LENGTH_LONG).show();
				}	
			}else{
				// khong co thong tin cap nhat moi
				Toast.makeText(this, "Không có thông tin cập nhật mới!", Toast.LENGTH_LONG).show();
			}
		}else{
			// bao loi tao user
			Toast.makeText(this, "Có lỗi xảy ra khi tạo user!", Toast.LENGTH_LONG).show();
		}
	}

	private HLCDTO[] sendRequestSync(UserDTO user){
		SoapObject response = ServiceSync.InvokeMethod(user);
		HLCDTO[] arrIR = null;
		// check response is null
		if(response != null && response.getPropertyCount() > 0){
			arrIR = RetrieveFromSoap(response);
		}else{
			arrIR = null;
		}
		return arrIR;
	}

	private HLCDTO[] RetrieveFromSoap(SoapObject response) {
		HLCDTO[] arrIR = new HLCDTO[response.getPropertyCount()];
		IRBUS irBus = new IRBUS();
		boolean bCheckDelete = irBus.deleteAllIR(this);
		if(bCheckDelete){
			for(int i = 0; i < arrIR.length; i++){
				SoapObject soTemp = (SoapObject)response.getProperty(i);
				HLCDTO ir = new HLCDTO();
				String sChoCapNhat = "Chờ cập nhật";
				
				if(soTemp.getProperty(0).toString().equals("anyType{}")){
					ir.setMa(String.valueOf(i));
				}else{
					ir.setMa(soTemp.getProperty(0).toString());
				}
				if(soTemp.getProperty(1).toString().equals("anyType{}")){
					ir.setTable(sChoCapNhat);
				}else{
					ir.setTable(soTemp.getProperty(1).toString());
				}
				if(soTemp.getProperty(2).toString().equals("anyType{}")){
					ir.setCommand(sChoCapNhat);
				}else{
					ir.setCommand(soTemp.getProperty(2).toString());
				}
				// add ir to arrIR
				arrIR[i] = ir;
			}
		}else{
			Toast.makeText(this, "Có lỗi xảy ra", Toast.LENGTH_LONG).show();
		}	
		return arrIR;
	}
	
	private List<HLCDTO> findDataUpdateFromIRAndDatabase(HLCDTO[] arrIRSource){
		List<HLCDTO> lstIR = new ArrayList<HLCDTO>();
		IRBUS irBus = new IRBUS();
		for(int i = 0; i < arrIRSource.length; i++){
			boolean checkExist = false;
			HLCDTO ir = arrIRSource[i];
			Entity entity = Entity.valueOf(ir.getTable());
			// use Table and check ir.Ma -> 
			switch(entity){
			case thuoc:
				// use Table Thuoc
				ThuocBUS thuocbus = new ThuocBUS();
				checkExist = thuocbus.checkExistId(Integer.parseInt(ir.getMa()), this);
				break;
			case socuu:
				break;
				default:
					break;
			}
			if(checkExist && ir.getCommand().compareTo("insert") == 0){
				// do nothing
			}else if(checkExist || ir.getCommand().compareTo("insert") == 0){
				//if exist in Table -> save to lstIR ; else -> do nothing
				lstIR.add(ir);
				boolean bInsertIR = irBus.saveIRtoDatabase(ir, this);
				if(bInsertIR){
					// IR has been inserted
				}else{
					// IR had not been inserted
					Toast.makeText(this, "Có lỗi xảy ra", Toast.LENGTH_LONG).show();
				}
			}else {
				// do nothing
			}
		}
		return lstIR;
	}

	private boolean lockRecordHaveIdInIR(HLCDTO[] arrIR) {
		boolean lockRecord = false;
		for(int i = 0; i < arrIR.length;i++){
			HLCDTO ir = arrIR[i];
			boolean checkLockRecord = false;
			Entity entity = Entity.valueOf(ir.getTable());
			switch(entity){
			case thuoc:
				// use Table Thuoc
				ThuocBUS thuocbus = new ThuocBUS();
				checkLockRecord = thuocbus.lockRecord(Integer.parseInt(ir.getMa()), this);
				break;
			case socuu:
				break;
				default:
					break;
			}
			if(checkLockRecord){
				// neu lock thanh cong
				lockRecord = true;
			}else{
				lockRecord = false;
				return lockRecord;
			}
		}
		return lockRecord;
	}

	private Data sendRequestDataUpdate(UserDTO user, Vector<HLCDTO> iR) {
		Data dataReceive = new Data();
		SoapObject so = ServiceSync.requestSyncDataUpdate(user, iR);
		if(so != null){
			dataReceive = parseDataReceive(so);
		}else{
			dataReceive = null;
		}
		return dataReceive;
	}
	
	private Vector<HLCDTO> convertListToVector(List<HLCDTO> listIR) {
		Vector<HLCDTO> myVec = new Vector<HLCDTO>();
        for (int i = 0; i < listIR.size(); i++) {
            myVec.addElement(listIR.get(i));
        }
        return myVec;
	}

	private Data parseDataReceive(SoapObject response) {
		Data data = new Data();
		//thuoc,chitiettoathuoc,phieukham,socuu,sokhambenh
		List<ThuocDTO> lstThuoc = processListThuoc(response, "List_thuoc");
		if(lstThuoc == null){
			// do nothing
		}else{
			data.setLstThuoc(lstThuoc);
			// lay het mathuoc tu bang thuoc ra
			ThuocBUS thuocBUS = new ThuocBUS();
			List<ThuocDTO> lstAllThuoc = thuocBUS.getAllThuocDTO(this);
			for(int i = 0; i < lstAllThuoc.size(); i++){
				ThuocDTO thuoc = lstAllThuoc.get(i);
				HLCDTO ir = new HLCDTO();
				ir.setMa(String.valueOf(thuoc.getMATHUOC()));
				ir.setTable("thuoc");
				ir.setCommand("");
				lstExistItems.add(ir);
			}
		}
//		List<SoCuuDTO> lstSoCuu = processListSoCuu(response, "LstSoCuu");
//		if(lstSoCuu == null){
//			// do nothing
//		}else{
//			data.setLstSoCuu(lstSoCuu);
//		}
		return data;
	}

	private List<ThuocDTO> processListThuoc(SoapObject response, String propertyName) {
		List<ThuocDTO> lstThuoc = new ArrayList<ThuocDTO>();
		if(response.hasProperty(propertyName)){
			SoapObject soLstThuoc = (SoapObject)response.getProperty(propertyName);
			for(int i = 0;i < soLstThuoc.getPropertyCount();i++){
				SoapObject soTemp = (SoapObject) soLstThuoc.getProperty(i);
				ThuocDTO thuocDTO = new ThuocDTO();
				String sChoCapNhat = "Chờ cập nhật";
				
				if(soTemp.getProperty(0).toString().equals("anyType{}")){
					thuocDTO.setMATHUOC(0);
				}else{
					thuocDTO.setMATHUOC(Integer.parseInt(soTemp.getProperty(0).toString()));
				}
				if(soTemp.getProperty(1).toString().equals("anyType{}")){
					thuocDTO.setMALOAITHUOC(0);
				}else{
					thuocDTO.setMALOAITHUOC(Integer.parseInt(soTemp.getProperty(1).toString()));
				}
				if(soTemp.getProperty(2).toString().equals("anyType{}")){
					thuocDTO.setHINHANH(sChoCapNhat);
				}else{
					thuocDTO.setHINHANH(soTemp.getProperty(2).toString());
				}
				if(soTemp.getProperty(3).toString().equals("anyType{}")){
					thuocDTO.setTENTHUOC(sChoCapNhat);
				}else{
					thuocDTO.setTENTHUOC(soTemp.getProperty(3).toString());
				}
				if(soTemp.getProperty(4).toString().equals("anyType{}")){
					thuocDTO.setSODANGKY(sChoCapNhat);
				}else{
					thuocDTO.setSODANGKY(soTemp.getProperty(4).toString());
				}
				if(soTemp.getProperty(5).toString().equals("anyType{}")){
					thuocDTO.setTHANHPHAN(sChoCapNhat);
				}else{
					thuocDTO.setTHANHPHAN(soTemp.getProperty(5).toString());
				}
				if(soTemp.getProperty(6).toString().equals("anyType{}")){
					thuocDTO.setDANGBAOCHE(sChoCapNhat);
				}else{
					thuocDTO.setDANGBAOCHE(soTemp.getProperty(6).toString());
				}
				if(soTemp.getProperty(7).toString().equals("anyType{}")){
					thuocDTO.setDONGGOI(sChoCapNhat);
				}else{
					thuocDTO.setDONGGOI(soTemp.getProperty(7).toString());
				}
				if(soTemp.getProperty(8).toString().equals("anyType{}")){
					thuocDTO.setCONGTYSANXUAT(sChoCapNhat);
				}else{
					thuocDTO.setCONGTYSANXUAT(soTemp.getProperty(8).toString());
				}
				if(soTemp.getProperty(9).toString().equals("anyType{}")){
					thuocDTO.setCHIDINH(sChoCapNhat);
				}else{
					thuocDTO.setCHIDINH(soTemp.getProperty(9).toString());
				}
				if(soTemp.getProperty(10).toString().equals("anyType{}")){
					thuocDTO.setCHONGCHIDINH(sChoCapNhat);
				}else{
					thuocDTO.setCHONGCHIDINH(soTemp.getProperty(10).toString());
				}
				if(soTemp.getProperty(11).toString().equals("anyType{}")){
					thuocDTO.setTUONGTACTHUOC(sChoCapNhat);
				}else{
					thuocDTO.setTUONGTACTHUOC(soTemp.getProperty(11).toString());	
				}
				if(soTemp.getProperty(12).toString().equals("anyType{}")){
					thuocDTO.setCHUYDEPHONG(sChoCapNhat);
				}else{
					thuocDTO.setCHUYDEPHONG(soTemp.getProperty(12).toString());
				}
				if(soTemp.getProperty(13).toString().equals("anyType{}")){
					thuocDTO.setTACDUNGPHU(sChoCapNhat);
				}else{
					thuocDTO.setTACDUNGPHU(soTemp.getProperty(13).toString());
				}
				if(soTemp.getProperty(14).toString().equals("anyType{}")){
					thuocDTO.setLIEULUONG(sChoCapNhat);
				}else{
					thuocDTO.setLIEULUONG(soTemp.getProperty(14).toString());
				}
				if(soTemp.getProperty(15).toString().equals("anyType{}")){
					thuocDTO.setBAOQUAN(sChoCapNhat);
				}else{
					thuocDTO.setBAOQUAN(soTemp.getProperty(15).toString());
				}
				if(soTemp.getProperty(16).toString().equals("anyType{}")){
					thuocDTO.setNHANBIET(sChoCapNhat);
				}else{
					thuocDTO.setNHANBIET(soTemp.getProperty(16).toString());
				}
				//save phanloaithuocDTO into Db
				ThuocBUS thuocBUS = new ThuocBUS();
				boolean bCheckThuocCommand= thuocBUS.checkThuocCommand(thuocDTO, this);
				if(bCheckThuocCommand){
					// thuocDTO had been inserted
				}else{
					// dua thuoc vao ds errorItems
					//Toast.makeText(this, "Có lỗi xảy ra", Toast.LENGTH_LONG).show();
					HLCDTO irError = new HLCDTO();
					irError.setMa(String.valueOf(thuocDTO.getMATHUOC()));
					irError.setTable("thuoc");
					irError.setCommand("");
					lstErrorItems.add(irError);
				}
				lstThuoc.add(thuocDTO);
			}
		}else{
			lstThuoc = null;
		}
		return lstThuoc;
	}
	
//	private List<SoCuuDTO> processListSoCuu(SoapObject response, String propertyName) {
//		List<SoCuuDTO> lstSoCuu = new ArrayList<SoCuuDTO>();
//		if(response.hasProperty(propertyName)){
//			SoapObject soLstSoCuu = (SoapObject)response.getProperty(propertyName);
//			for(int i = 0;i < soLstSoCuu.getPropertyCount();i++){
//				SoapObject soTemp = (SoapObject) soLstSoCuu.getProperty(i);
//				SoCuuDTO soCuuDTO = new SoCuuDTO();
//				String sChoCapNhat = "Chờ cập nhật";
//				
//				// xu ly thuoc tinh
//				
//				//save socuuDTO into Db
//				SoCuuBUS socuuBUS = new SoCuuBUS();
//				boolean bCheckSoCuuCommand= socuuBUS.checkSoCuuCommand(soCuuDTO, this);
//				if(bCheckSoCuuCommand){
//					// socuuDTO had been inserted
//				}else{
//					Toast.makeText(this, "Có lỗi xảy ra", Toast.LENGTH_LONG).show();;
//				}
//				lstSoCuu.add(soCuuDTO);
//			}
//		}else{
//			lstSoCuu = null;
//		}
//		return lstSoCuu;
//	}

	private boolean sendConfirmSyncedData(UserDTO user, Vector<HLCDTO> vExistItems, Vector<HLCDTO> vErrorItems) {
		boolean checkSend = false;
		try{
			SoapObject so = ServiceSync.sendConfirmSyncedData(user, vExistItems, vErrorItems);
			if(so != null){
				checkSend = true;
			}else{
				checkSend = false;
			}
		}catch(Exception ex){
			checkSend = false;
			return checkSend;
		}
		return checkSend;
	}
}
